package com.zxjbyte.yiyi.framework.common.core.okhttp.retry;

import cn.hutool.core.lang.Singleton;
import com.github.rholder.retry.Attempt;
import com.github.rholder.retry.RetryListener;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Consumer;

/**
 * 简答的重试监听器
 * @Author zhangxingjia
 * @Date 2024/3/16 13:43
 * @Version: 1.0
 */
@Slf4j
public class SimpleRetryListener implements RetryListener {

    private Integer attemptNumberLimit;
    private Consumer<Throwable> exceptionConsumer;


    public static SimpleRetryListener of(){
        return Singleton.get(SimpleRetryListener.class);
    }

    public static SimpleRetryListener of(Integer attemptNumberLimit, Consumer<Throwable> exceptionConsumer){
        return Singleton.get(SimpleRetryListener.class, attemptNumberLimit, exceptionConsumer);
    }

    public SimpleRetryListener(){
    }

    public SimpleRetryListener(Integer attemptNumberLimit, Consumer<Throwable> exceptionConsumer){
        this.attemptNumberLimit = attemptNumberLimit;
        this.exceptionConsumer = exceptionConsumer;
    }

    @Override
    public <V> void onRetry(Attempt<V> attempt) {
        // 第一次重试就是第一次调用
        log.info("Attempt Number >>> {}", attempt.getAttemptNumber());

        // 当时重试超过限制数，可自定义消费异常，例如发送警告邮件，短信等等
        if(attemptNumberLimit != null && exceptionConsumer != null){
            if(attempt.getAttemptNumber() >= attemptNumberLimit && attempt.hasException()){
                Throwable t = attempt.getExceptionCause();
                exceptionConsumer.accept(t);
            }
        }
        if(attempt.hasException()){
            log.error("Retry hasException >>> {}", attempt.getExceptionCause().toString());
        } else {
            log.info("Retry result >>> {}", attempt.getResult());
        }
    }
}
